{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys as sys\n",
    "#reload(sys)\n",
    "#sys.setdefaultencoding('utf-8')\n",
    "from sklearn.cluster import KMeans\n",
    "from sklearn import feature_extraction\n",
    "from sklearn.feature_extraction.text import TfidfTransformer\n",
    "from sklearn.feature_extraction.text import CountVectorizer\n",
    "\n",
    "import matplotlib.pyplot as plt \n",
    "from matplotlib.font_manager import FontProperties \n",
    "from sklearn.cluster import KMeans \n",
    "from scipy.spatial.distance import cdist \n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "vectorize the input documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def tfidf_vector(corpus_path):\n",
    "    corpus_train=[]\n",
    "    #利用train-corpus提取特征\n",
    "    target_train=[]\n",
    "    for line in open(corpus_path):\n",
    "        line=line.strip().split('\\t')\n",
    "        if len(line)==2:\n",
    "            words=line[1]\n",
    "            category=line[0]\n",
    "            target_train.append(category)\n",
    "            corpus_train.append(words)\n",
    "    print (\"build train-corpus done!!\")\n",
    "    count_v1= CountVectorizer(max_df=0.4,min_df=0.01)\n",
    "    counts_train = count_v1.fit_transform(corpus_train)  \n",
    "    \n",
    "    word_dict={}\n",
    "    for index,word in enumerate(count_v1.get_feature_names()):\n",
    "        word_dict[index]=word\n",
    "    \n",
    "    print (\"the shape of train is \")\n",
    "    print (repr(counts_train.shape))\n",
    "    tfidftransformer = TfidfTransformer()\n",
    "    tfidf_train = tfidftransformer.fit(counts_train).transform(counts_train)\n",
    "    return tfidf_train,word_dict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "topic cluster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cluster_kmeans(tfidf_train,word_dict,cluster_docs,cluster_keywords,num_clusters):#K均值分类\n",
    "    f_docs=open(cluster_docs,'w+')\n",
    "    km = KMeans(n_clusters=num_clusters)\n",
    "    km.fit(tfidf_train)\n",
    "    clusters = km.labels_.tolist()\n",
    "    cluster_dict={}\n",
    "    order_centroids = km.cluster_centers_.argsort()[:, ::-1]      \n",
    "    doc=1\n",
    "    for cluster in clusters:\n",
    "        f_docs.write(str(str(doc))+','+str(cluster)+'\\n')\n",
    "        doc+=1\n",
    "        if cluster not in cluster_dict:\n",
    "            cluster_dict[cluster]=1\n",
    "        else:\n",
    "            cluster_dict[cluster]+=1\n",
    "    f_docs.close()\n",
    "    cluster=1\n",
    "    \n",
    "    f_clusterwords = open(cluster_keywords,'w+')\n",
    "    for ind in order_centroids: # 每个聚类选 50 个词\n",
    "        words=[]\n",
    "        for index in ind[:50]:\n",
    "            words.append(word_dict[index])\n",
    "        print (cluster),(','.join(words))\n",
    "        f_clusterwords.write(str(cluster)+'\\t'+','.join(words)+'\\n')\n",
    "        cluster+=1\n",
    "        print ('*****'*5)\n",
    "    f_clusterwords.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "select the best cluster num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def best_kmeans(tfidf_matrix,word_dict):  \n",
    "    K = range(1, 10) \n",
    "    meandistortions = [] \n",
    "    for k in K: \n",
    "        print (k),('****'*5)\n",
    "        kmeans = KMeans(n_clusters=k) \n",
    "        kmeans.fit(tfidf_matrix)    \n",
    "        meandistortions.append(sum(np.min(cdist(tfidf_matrix.toarray(), kmeans.cluster_centers_, 'euclidean'), axis=1)) / tfidf_matrix.shape[0]) \n",
    "    plt.plot(K, meandistortions, 'bx-')\n",
    "    plt.grid(True) \n",
    "    plt.xlabel('Number of clusters') \n",
    "    plt.ylabel('Average within-cluster sum of squares') \n",
    "    plt.title('Elbow for Kmeans clustering')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Main启动"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "build train-corpus done!!\n",
      "the shape of train is \n",
      "(1610, 362)\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ERROR:root:Internal Python error in the inspect module.\n",
      "Below is the traceback from this internal error.\n",
      "\n",
      "Error in sys.excepthook:\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2061, in showtraceback\n",
      "    stb = value._render_traceback_()\n",
      "AttributeError: 'KeyboardInterrupt' object has no attribute '_render_traceback_'\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2063, in showtraceback\n",
      "    stb = self.InteractiveTB.structured_traceback(etype,\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 1367, in structured_traceback\n",
      "    return FormattedTB.structured_traceback(\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 1267, in structured_traceback\n",
      "    return VerboseTB.structured_traceback(\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 1124, in structured_traceback\n",
      "    formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 1082, in format_exception_as_a_whole\n",
      "    last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 382, in find_recursion\n",
      "    return len(records), 0\n",
      "TypeError: object of type 'NoneType' has no len()\n",
      "\n",
      "Original exception was:\n",
      "Traceback (most recent call last):\n",
      "  File \"<__array_function__ internals>\", line 2, in where\n",
      "KeyboardInterrupt\n",
      "Exception ignored in: 'sklearn.cluster._k_means_fast._relocate_empty_clusters_sparse'\n",
      "Traceback (most recent call last):\n",
      "  File \"<__array_function__ internals>\", line 2, in where\n",
      "KeyboardInterrupt: \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Traceback (most recent call last):\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2061, in showtraceback\n",
      "    stb = value._render_traceback_()\n",
      "AttributeError: 'KeyboardInterrupt' object has no attribute '_render_traceback_'\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 1101, in get_records\n",
      "    return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 248, in wrapped\n",
      "    return f(*args, **kwargs)\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\site-packages\\IPython\\core\\ultratb.py\", line 281, in _fixed_getinnerframes\n",
      "    records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\inspect.py\", line 1503, in getinnerframes\n",
      "    frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\inspect.py\", line 1461, in getframeinfo\n",
      "    filename = getsourcefile(frame) or getfile(frame)\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\inspect.py\", line 708, in getsourcefile\n",
      "    if getattr(getmodule(object, filename), '__loader__', None) is not None:\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\inspect.py\", line 754, in getmodule\n",
      "    os.path.realpath(f)] = module.__name__\n",
      "  File \"D:\\LangSDK\\python\\python3.8\\lib\\ntpath.py\", line 647, in realpath\n",
      "    path = _getfinalpathname(path)\n",
      "KeyboardInterrupt\n",
      "9\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "*************************\n",
      "2\n",
      "*************************\n",
      "3\n",
      "*************************\n",
      "4\n",
      "*************************\n",
      "5\n",
      "*************************\n",
      "6\n",
      "*************************\n",
      "7\n",
      "*************************\n"
     ]
    }
   ],
   "source": [
    "corpus_train = \"corpus_train.txt\"\n",
    "cluster_docs = \"cluster_result_document.txt\"\n",
    "cluster_keywords = \"cluster_result_keyword.txt\"\n",
    "num_clusters = 7\n",
    "tfidf_train,word_dict=tfidf_vector(corpus_train)\n",
    "best_kmeans(tfidf_train,word_dict)\n",
    "cluster_kmeans(tfidf_train,word_dict,cluster_docs,cluster_keywords,num_clusters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "pycharm-bea11b57",
   "language": "python",
   "display_name": "PyCharm (ML-NLP)"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}